package cc.rengu.igas.momp.core.service.trans;

import cc.rengu.igas.momp.common.constant.CommonConstant;
import cc.rengu.igas.momp.common.dao.CouponInfoMapper;
import cc.rengu.igas.momp.common.dao.McDetailInfoMapper;
import cc.rengu.igas.momp.common.dao.impl.CouponInfoMapperImpl;
import cc.rengu.igas.momp.common.dao.impl.McDetailInfoMapperImpl;
import cc.rengu.igas.momp.common.entity.TMCouponInfo;
import cc.rengu.igas.momp.common.entity.TMMcCouponInfo;
import cc.rengu.igas.momp.common.enums.CouponStatusEnum;
import cc.rengu.igas.momp.common.enums.RespCodeEnum;
import cc.rengu.igas.momp.facade.bean.CouponBriefInfoBean;
import cc.rengu.igas.momp.facade.request.ReturnCouponRequest;
import cc.rengu.igas.momp.facade.response.ReturnCouponResponse;
import cc.rengu.jradp.mods.dbs.Database;
import cc.rengu.oltp.service.base.RadpService;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.enums.ChannelEnum;
import cc.rengu.oltp.service.common.enums.OltpRpcdEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.utility.util.ConvertUtil;
import cc.rengu.oltp.utility.util.XmlTreeUtil;
import cc.rengu.utility.base.StringUtil;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * 卡券退回功能实现
 *
 * @author Jinan Liu
 * @date 2020/4/2 17:49
 */
public class ReturnCouponService extends RadpService {

    private String globalInstId;
    private String globalTimeStamp;

    @Override
    protected int bizInit(String s) {
        return CommonConstant.PROCESS_SUCCESS;
    }

    @Override
    protected int bizProcess(String s, int i) {

        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();

        try {

            ReturnCouponRequest returnCouponRequest = new ReturnCouponRequest();
            ConvertUtil.convertOutput(returnCouponRequest);

            ReturnCouponResponse returnCouponResponse = new ReturnCouponResponse();
            returnCouponResponse.setHeader(returnCouponRequest.getHeader());
            BizResponse<ReturnCouponResponse> bizResponse = new BizResponse<>();
            bizResponse.setResult(returnCouponResponse);

            globalInstId = returnCouponRequest.getHeader().getInstId();
            globalTimeStamp = new SimpleDateFormat(CommonConstant.TIMESTAMP_FORMAT).format(new Date());

            // 服务调用
            BizResponse<ReturnCouponResponse> bizResponseNew = returnCoupon(returnCouponRequest, returnCouponResponse);

            ConvertUtil.convertInput(bizResponseNew.getResult());

        } catch (BizException e) {
            try {
                xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.RESP_CODE, e.getCode());
                xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.RESP_DESC, e.getMessage());
            } catch (Exception e1) {
                rglog.error(StringUtil.ExceptionToString(e1));
            }
        } catch (Exception e) {
            rglog.error(StringUtil.ExceptionToString(e));
            try {
                xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.RESP_CODE, OltpRpcdEnum.OLTP_PROCESS_ERROR.getRespCode());
                xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.RESP_DESC, OltpRpcdEnum.OLTP_PROCESS_ERROR.getRespDesc());
            } catch (Exception e1) {
                rglog.error(StringUtil.ExceptionToString(e));
            }
        }

        return CommonConstant.PROCESS_SUCCESS;
    }

    @Override
    protected int bizTerminate(String s) {
        return CommonConstant.PROCESS_SUCCESS;
    }

    /**
     * 卡券回退流程
     * 仅可退回未核销卡券,不可退回已核销卡券
     *
     * @param returnCouponRequest  卡券退回接口请求对象
     * @param returnCouponResponse 卡券退回接口应答对象
     * @return cc.rengu.oltp.service.model.BizResponse<cc.rengu.igas.momp.facade.response.ReturnCouponResponse> 卡券退回接口应答对象
     * @throws Exception 异常信息
     * @author Jinan Liu
     * @date 2020/6/2 09:17
     */
    private BizResponse<ReturnCouponResponse> returnCoupon(ReturnCouponRequest returnCouponRequest, ReturnCouponResponse returnCouponResponse) throws BizException {

        BizResponse<ReturnCouponResponse> bizResponse = new BizResponse<>();

        returnCouponList(returnCouponRequest);

        bizResponse.setRspSysId(ChannelEnum.MOMP.getChannelType());
        bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());

        returnCouponResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        returnCouponResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        bizResponse.setResult(returnCouponResponse);

        return bizResponse;
    }

    /**
     * 卡券批量退回
     *
     * @param returnCouponRequest 卡券退回接口请求对象
     * @author Jinan Liu
     * @date 2020/4/7 18:04
     */
    private void returnCouponList(ReturnCouponRequest returnCouponRequest) {

        List<CouponBriefInfoBean> couponBriefInfoBeanList = returnCouponRequest.getCouponInfoList();

        try {
            couponBriefInfoBeanList.forEach(this::returnSingleCoupon);
        } catch (Exception e) {
            rglog.error("转换营销活动信息异常,异常信息:<{}>", StringUtil.ExceptionToString(e));
            throw new BizException(RespCodeEnum.SYSTEM_ERROR.getRespCode(), RespCodeEnum.SYSTEM_ERROR.getRespDesc());
        }
    }

    /**
     * 单个卡券退回
     *
     * @param couponBriefInfoBean 卡券简要信息对象
     * @author Jinan Liu
     * @date 2020/4/7 18:04
     */
    private void returnSingleCoupon(CouponBriefInfoBean couponBriefInfoBean) {

        try {
            /* 根据锁定标志判断业务流程 */
            switch (couponBriefInfoBean.getCouponLockFlag()) {
                case CommonConstant.CLAIM_COUPON_LOCK:
                    /* 锁定卡券 */
                    lockSingleCoupon(couponBriefInfoBean);
                    break;
                case CommonConstant.CLAIM_COUPON_UNLOCK_S:
                    /* 解锁卡券，并退回卡券 */
                    unlockSingleCouponForReturn(couponBriefInfoBean);
                    break;
                case CommonConstant.CLAIM_COUPON_UNLOCK_F:
                    /* 解锁卡券，并解除退回状态 */
                    unlockSingleCouponForFailure(couponBriefInfoBean);
                    break;
                default:
                    rglog.error("不支持的锁定标志! LOCK_FLAG=<{}>", couponBriefInfoBean.getCouponLockFlag());
                    throw new BizException(RespCodeEnum.SYSTEM_ERROR.getRespCode(), RespCodeEnum.SYSTEM_ERROR.getRespDesc());
            }

        } catch (Exception e) {
            rglog.error(StringUtil.ExceptionToString(e));
            throw new BizException(RespCodeEnum.SYSTEM_ERROR.getRespCode(), RespCodeEnum.SYSTEM_ERROR.getRespDesc());
        }
    }

    /**
     * 退回卡券时锁定指定卡券的卡券状态
     *
     * @param couponBriefInfoBean 卡券简要信息对象
     * @author Jinan Liu
     * @date 2020/6/1 17:42
     */
    private void lockSingleCoupon(CouponBriefInfoBean couponBriefInfoBean) {

        String couponNo = couponBriefInfoBean.getCouponNo();

        try {

            /* 查询卡券信息 */
            TMCouponInfo couponInfo = new TMCouponInfo();
            couponInfo.setInstId(globalInstId);
            couponInfo.setCouponNo(couponNo);

            /* 根据卡券编号查询卡券信息 */
            TMCouponInfo tmCouponInfo = selectSingleCouponInfoByCouponNo(couponInfo);
            if (null == tmCouponInfo) {
                rglog.error("法人机构<{}>的卡券编号<{}>的卡券信息查询失败!", globalInstId, couponNo);
                throw new BizException(RespCodeEnum.FAILED_TO_QUERY_COUPON_INFO_ERROR.getRespCode(), RespCodeEnum.FAILED_TO_QUERY_COUPON_INFO_ERROR.getRespDesc());
            }

            /* 检查卡券状态 */
            if (!CouponStatusEnum.NOT_REDEEMED.getCouponStatusCode().equals(tmCouponInfo.getCouponStatus())) {
                rglog.error("法人机构<{}>的卡券编号<{}>的卡券不是未核销状态,不可回退! COUPON_STATUS=<{}>", globalInstId, couponNo, tmCouponInfo.getCouponStatus());
                throw new BizException(RespCodeEnum.FAILED_TO_QUERY_COUPON_INFO_ERROR.getRespCode(), RespCodeEnum.FAILED_TO_QUERY_COUPON_INFO_ERROR.getRespDesc());
            }

            /* 更新卡券状态 */
            couponInfo.setInstId(globalInstId);
            couponInfo.setCouponNo(couponNo);
            couponInfo.setCouponNo(CouponStatusEnum.LOCKED.getCouponStatusCode());
            couponInfo.setRemark1(tmCouponInfo.getCouponStatus());
            int returnCode = updateCouponStatusByPrimaryKey(tmCouponInfo);
            if (cc.rengu.utility.dbs.Database.DBS_SUCCESS != returnCode) {
                rglog.error("更新卡券状态失败! RETURN_CODE=<{}>", returnCode);
                throw new BizException(RespCodeEnum.FAILED_UPDATE_COUPON_STATUS_ERROR.getRespCode(), RespCodeEnum.FAILED_UPDATE_COUPON_STATUS_ERROR.getRespDesc());
            }

        } catch (Exception e) {
            rglog.error(StringUtil.ExceptionToString(e));
            throw new BizException(RespCodeEnum.SYSTEM_ERROR.getRespCode(), RespCodeEnum.SYSTEM_ERROR.getRespDesc());
        }
    }

    /**
     * 领取卡券时第二次调用解锁指定卡券并领取卡券
     *
     * @param couponBriefInfoBean 卡券简要信息对象
     * @author Jinan Liu
     * @date 2020/6/1 17:42
     */
    private void unlockSingleCouponForReturn(CouponBriefInfoBean couponBriefInfoBean) {

        String couponNo = couponBriefInfoBean.getCouponNo();

        try {
            /* 根据卡券编号查询卡券基本信息 */
            TMCouponInfo couponInfo = new TMCouponInfo();
            couponInfo.setInstId(globalInstId);
            couponInfo.setCouponNo(couponNo);

            /* 根据卡券编号查询已锁定的卡券信息 */
            TMCouponInfo tmCouponInfo = selectLockedCouponByPrimaryKey(couponInfo);
            if (null == tmCouponInfo) {
                rglog.error("法人机构<{}>的卡券编号<{}>的卡券信息查询失败!", globalInstId, couponNo);
                throw new BizException(RespCodeEnum.FAILED_TO_QUERY_COUPON_INFO_ERROR.getRespCode(), RespCodeEnum.FAILED_TO_QUERY_COUPON_INFO_ERROR.getRespDesc());
            }

            couponInfo.setInstId(globalInstId);
            couponInfo.setCouponNo(couponNo);
            couponInfo.setClaimUserId(CommonConstant.EMPTY_STRING);
            couponInfo.setClaimDate(CommonConstant.EMPTY_STRING);
            couponInfo.setClaimTime(CommonConstant.EMPTY_STRING);
            couponInfo.setClaimType(CommonConstant.EMPTY_STRING);
            couponInfo.setUpdateTime(globalTimeStamp);
            couponInfo.setCouponStatus(CouponStatusEnum.NOT_ENABLED.getCouponStatusCode());

            /* 取卡券营销活动基本信息 */
            TMMcCouponInfo tmMcCouponInfo;
            tmMcCouponInfo = selectCouponMcInfoByPrimaryKey(globalInstId, tmCouponInfo.getMcNo());
            if (null == tmMcCouponInfo) {
                rglog.error("法人机构<{}>的卡券营销活动<{}>的基本信息查询失败!", globalInstId, tmCouponInfo.getMcNo());
                throw new BizException(RespCodeEnum.GET_COUPON_MC_DETAIL_ERROR.getRespCode(), RespCodeEnum.GET_COUPON_MC_DETAIL_ERROR.getRespDesc());
            }

            /* 根据卡券有效期生成卡券有效期起止日期 */
            int returnCode;
            if (CommonConstant.COUPON_RELATIVE_DATE.equals(tmMcCouponInfo.getCouponDateFlag())) {
                /* 计算卡券有效起止日期并更新 */
                tmCouponInfo.setCouponStartDate(CommonConstant.EMPTY_STRING);
                tmCouponInfo.setCouponEndDate(CommonConstant.EMPTY_STRING);

                /* 更新卡券状态 */
                returnCode = updateLockedCouponInfoAndDate(couponInfo);

            } else {
                /* 不需要更新卡券有效期止日期,更新卡券状态 */
                returnCode = updateLockedCouponInfo(couponInfo);
            }

            if (Database.DBS_SUCCESS != returnCode) {
                rglog.error("更新卡券状态失败! RETURN_CODE=<{}>", returnCode);
                throw new BizException(RespCodeEnum.FAILED_UPDATE_COUPON_STATUS_ERROR.getRespCode(), RespCodeEnum.FAILED_UPDATE_COUPON_STATUS_ERROR.getRespDesc());
            }

        } catch (Exception e) {
            rglog.error(StringUtil.ExceptionToString(e));
            throw new BizException(RespCodeEnum.SYSTEM_ERROR.getRespCode(), RespCodeEnum.SYSTEM_ERROR.getRespDesc());
        }
    }

    /**
     * 领取卡券时第二次调用解锁指定卡券并退回卡券
     *
     * @param couponBriefInfoBean 卡券简要信息对象
     * @return cc.rengu.igas.momp.facade.bean.CouponListInfoBean 卡券列表信息对象
     * @author Jinan Liu
     * @date 2020/6/1 17:42
     */
    private void unlockSingleCouponForFailure(CouponBriefInfoBean couponBriefInfoBean) {

        /* 营销活动信息正式表查询 */
        String couponNo = couponBriefInfoBean.getCouponNo();

        try {
            /* 根据卡券编号查询卡券基本信息 */
            TMCouponInfo couponInfo = new TMCouponInfo();
            couponInfo.setInstId(globalInstId);
            couponInfo.setCouponNo(couponNo);

            /* 根据卡券编号查询已锁定的卡券信息 */
            TMCouponInfo tmCouponInfo = selectLockedCouponByPrimaryKey(couponInfo);
            if (null == tmCouponInfo) {
                rglog.error("法人机构<{}>的卡券编号<{}>的卡券信息查询失败!", globalInstId, couponNo);
                throw new BizException(RespCodeEnum.FAILED_TO_QUERY_COUPON_INFO_ERROR.getRespCode(), RespCodeEnum.FAILED_TO_QUERY_COUPON_INFO_ERROR.getRespDesc());
            }

            /* 更新卡券状态 */
            couponInfo.setInstId(globalInstId);
            couponInfo.setCouponNo(couponNo);
            couponInfo.setCouponStatus(CouponStatusEnum.NOT_REDEEMED.getCouponStatusCode());
            couponInfo.setRemark1(CouponStatusEnum.LOCKED.getCouponStatusCode());
            int returnCode = updateCouponStatusByPrimaryKey(tmCouponInfo);
            if (cc.rengu.utility.dbs.Database.DBS_SUCCESS != returnCode) {
                rglog.error("更新卡券状态失败! RETURN_CODE=<{}>", returnCode);
                throw new BizException(RespCodeEnum.FAILED_UPDATE_COUPON_STATUS_ERROR.getRespCode(), RespCodeEnum.FAILED_UPDATE_COUPON_STATUS_ERROR.getRespDesc());
            }

        } catch (Exception e) {
            rglog.error(StringUtil.ExceptionToString(e));
            throw new BizException(RespCodeEnum.SYSTEM_ERROR.getRespCode(), RespCodeEnum.SYSTEM_ERROR.getRespDesc());
        }
    }

    /**
     * 使用卡券编号获取卡券信息
     *
     * @param tmCouponInfo 卡券信息表
     * @return cc.rengu.igas.momp.common.entity.TMCouponInfo 卡券信息表
     * @throws Exception 异常信息
     * @author Jinan Liu
     * @date 2020/6/2 09:58
     */
    private TMCouponInfo selectSingleCouponInfoByCouponNo(TMCouponInfo tmCouponInfo) throws Exception {

        CouponInfoMapper couponInfoMapper = new CouponInfoMapperImpl();
        return couponInfoMapper.selectSingleCouponInfoByCouponNo(tmCouponInfo);
    }

    /**
     * 更新卡券状态
     *
     * @param tmCouponInfo 卡券信息表
     * @return int 返回码
     * @throws Exception 异常信息
     * @author Jinan Liu
     * @date 2020/6/1 18:36
     */
    private int updateCouponStatusByPrimaryKey(TMCouponInfo tmCouponInfo) throws Exception {

        CouponInfoMapper couponInfoMapper = new CouponInfoMapperImpl();
        return couponInfoMapper.updateCouponStatusByPrimaryKey(tmCouponInfo);
    }

    /**
     * 查询已锁定卡券信息
     *
     * @param tmCouponInfo 卡券信息表
     * @return cc.rengu.igas.momp.common.entity.TMCouponInfo 卡券信息表
     * @throws Exception 异常信息
     * @author Jinan Liu
     * @date 2020/6/1 20:05
     */
    private TMCouponInfo selectLockedCouponByPrimaryKey(TMCouponInfo tmCouponInfo) throws Exception {

        CouponInfoMapper couponInfoMapper = new CouponInfoMapperImpl();
        return couponInfoMapper.selectLockedCouponByPrimaryKey(tmCouponInfo);
    }

    /**
     * 查询卡券营销活动基本信息
     *
     * @param instId 法人机构号
     * @param mcNo   营销活动编号
     * @return cc.rengu.igas.momp.common.entity.TMMcCouponInfo 卡券类营销活动信息表
     * @author Jinan Liu
     * @date 2020/4/7 14:34
     */
    private TMMcCouponInfo selectCouponMcInfoByPrimaryKey(String instId, String mcNo) throws Exception {

        /* 营销活动信息正式表查询 */
        TMMcCouponInfo mcCouponInfo = new TMMcCouponInfo();
        mcCouponInfo.setInstId(instId);
        mcCouponInfo.setMcNo(mcNo);

        McDetailInfoMapper mcDetailInfoMapper = new McDetailInfoMapperImpl();
        return mcDetailInfoMapper.selectCouponMcInfoByPrimaryKey(mcCouponInfo);
    }

    /**
     * 更新已锁定卡券相关信息
     *
     * @param tmCouponInfo 卡券信息
     * @return int
     * @throws Exception 异常信息
     * @author Jinan Liu
     * @date 2020/4/7 14:55
     */
    private int updateLockedCouponInfo(TMCouponInfo tmCouponInfo) throws Exception {

        CouponInfoMapper couponInfoMapper = new CouponInfoMapperImpl();
        return couponInfoMapper.updateLockedCouponInfo(tmCouponInfo);
    }

    /**
     * 更新已锁定卡券相关信息和卡券有效期
     *
     * @param tmCouponInfo 卡券信息
     * @return int
     * @throws Exception 异常信息
     * @author Jinan Liu
     * @date 2020/4/7 14:55
     */
    private int updateLockedCouponInfoAndDate(TMCouponInfo tmCouponInfo) throws Exception {

        CouponInfoMapper couponInfoMapper = new CouponInfoMapperImpl();
        return couponInfoMapper.updateLockedCouponInfoAndDate(tmCouponInfo);
    }
}
